The present invention relates to digital data processing systems, and in particular to performance analysis of computer programming code.
Since the dawn of the computer age, computer systems have evolved into extremely sophisticated devices, and computer systems may be found in many different settings. Computer systems typically include a combination of hardware, such as semiconductors and circuit boards, and software, also known as computer programs. As advances in semiconductor processing and computer architecture push the performance of the computer hardware higher, more sophisticated computer software has evolved to take advantage of the higher performance of the hardware, resulting in computer systems today that are much more powerful than just a few years ago.
Computer systems typically include operating system software that controls the basic function of the computer, and one or more software application programs that run under the control of the operating system to perform desired tasks. For example, a typical IBM Personal Computer may run the Microsoft Windows operating system, and under the control of the operating system, a user may execute an application program, such as a word processor. As the capabilities of computer systems have increased, the application software programs designed for high performance computer systems have become extremely powerful. Additionally, software development costs have continued to rise because more powerful and complex programs take more time, and hence more money, to produce.
One way in which the performance of application software programs has been improved while the associated development costs have been reduced is by using object oriented programming concepts. The goal of using object oriented programming is to create small, reusable sections of program code known as xe2x80x9cobjectsxe2x80x9d that can be quickly and easily combined and re-used to create new programs. This is similar to the idea of using the same set of building blocks again and again to create many different structures. The modular and re-usable aspects of objects will typically speed development of new programs, thereby reducing the costs associated with the development cycle. In addition, by creating and re-using a comprehensive set of well-tested objects, a more stable, uniform, and consistent approach to developing new computer programs can be achieved.
Various programming languages have been developed to support the object oriented programming approach. The JAVA programming language developed by Sun Microsystems is one modern object oriented programming language that has become very popular in recent years. From a programmer""s point of view, one of the advantages of the JAVA programming language is that memory allocation and reclamation are handled entirely by the run-time system, which relieves the programmer of the burden of determining how and when to destroy unneeded objects. All objects (other than those of primitive types) are allocated from a common xe2x80x9cheapxe2x80x9d, or section of memory. The garbage collection mechanism then monitors the objects in the heap, and periodically deletes unneeded objects, thereby reclaiming portions of the heap that are occupied by objects that can no longer be accessed from the user""s program.
One problem with the JAVA automatic allocation and reclamation of memory is that users have less control over their program""s performance. Each time an object is allocated, a certain cost is incurred as the memory manager updates its data structures. Furthermore, an additional cost must be paid to reclaim the object during garbage collection. Although these costs are small when considered individually, the sheer frequency of object allocation and reclamation result in a significant portion of program execution time being spent in the memory manager, allocating and reclaiming memory for objects.
This problem is further compounded by the fact that it is difficult for a programmer to know how many objects are being created by a program. One of the pervasive concepts of object oriented programming is encapsulation. Encapsulation means that the internal structure and methods of reusable objects are hidden. Programmers are intended to access a reusable object via a defined interface, without concerning themselves with what goes on inside. Using the interface in accordance with its definition ensures that the program will behave in a predictable manner. But it does not assure any particular level of performance. With the internal details hidden, a programmer calling a method does not necessarily know what the performance consequences of that call might be, and in particular, does not know how many objects will be created as a result of the call.
As a result of these and other considerations, it has often been observed that a program written in an object oriented language and using reusable objects executes in a disappointingly slow manner, and in particular, executes more slowly than one would expect of a similar function written in a more traditional procedural language. Considerable research has therefore been directed to improving the performance of object oriented programs. For example, efforts have been made to design more intelligent compilers, which can identify common inefficiencies in object oriented source code and perform optimizations in the compiled code which avoid them.
Among the tools available to programmers and researchers are performance analyzers which monitor the execution of an object oriented program in order to identify bottlenecks. Typically, a performance analyzer has the capability to trace certain events which are considered significant to analyzing performance and program flow, such as the calling of a procedure or method, the occurrence of an exception condition, and the like. Since it is known that the creation of an object imposes a certain performance penalty, some conventional performance analyzers have the capability to trace the creation of objects in an object oriented program. I.e, these tools can identify each object creation event, and the method which caused an object to be created.
While conventional performance tools provide considerable assistance to programmers and researchers, there are many instances where the information provided could be improved. Although object creation imposes a performance penalty, the mere fact that a particular method created the object is often not very useful information. Many methods create, manipulate and store objects within the method. But it is also common in object oriented programming to write special methods for object creation, which typically create the object and initialize it to some default state, without doing anything more. In this case it is usual that any time an object of a class X is created, the same method (e.g. Cheate X) does so. A need exists, which is not necessarily recognized, to provide the programmer with more useful information concerning object creation.
In accordance with the present invention, a performance analyzer for object-oriented programming code distinguishes between different types of object uses. Specifically, a performance analyzer distinguishes between an object which is substantively used within the creating method, and one which is merely created in the creating method and passed back to a calling method.
In the preferred embodiment, a trace record is generated when the object is first used in some meaningful manner, to indicate the method which caused the operation. Preferably, an object is deemed first used when it is first xe2x80x9caccessedxe2x80x9d, meaning that certain method calls are made on the object or certain fields read.
In the preferred embodiment, an additional bit is added to each object""s header, which indicates whether the object has been accessed. When the object is first created a normal object create trace record is generated and the bit is cleared. When the object is first accessed, the bit is set and an object access trace record is generated. A subsequent object access (i.e., after the bit is set) does not cause a corresponding object access trace record to be generated.
In one embodiment, the performance analyzer may parse the trace to determine whether an object access trace record occurred in the creating method, or in some other method. The performance analyzer will treat the two cases differently. For example, it may delete object access trace records in the creating method, or it may omit them from certain statistical compilations.
Preferably, the program being analyzed is written in JAVA, and the performance analyzer is an instrumented JAVA Virtual Machine (JVM), i.e., a JVM to which trace and/or other performance analytic capabilities are added, potentially expanding the size of the object header to accommodate performance data.
By identifying the method in which an object is first accessed as explained above, the programmer is offered more useful analytical information. If the object is first accessed in a method other than the creating method, then it can be inferred that the creating method is a mere agent which is not the underlying cause of the object creation. If this first accessing method appears to be responsible for creating too many objects, the programmer may wish to modify the method to reduce the number of objects that must be created.
The details of the present invention, both as to its structure and operation, can best be understood in reference to the accompanying drawings, in which like reference numerals refer to like parts, and in which: